package com.lagou.client.thread;

import com.lagou.client.util.ZkClientUtil;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Kirito
 * @description: 客户端监听服务响应时间变化类
 * @date 2020/06/05
 */
@Component
public class ClientWatchTask {

    private final Logger log = LoggerFactory.getLogger(ClientWatchTask.class);

    @Scheduled(cron = "0/5 * * * * ?")
    private void run() {

        /**
         * 任务每5s执行一次，扫面所有/servers的服务都信息及其响应时间
         * 判断：假设localhost:8081子节点的数据最近一次修改时间为当前时间5s以前，则表示该节点超过5s没有请求，需要将响应时间置为0
         */
        long baseTime = System.currentTimeMillis();
        String parent = "/servers";
        ZkClient zkClient = ZkClientUtil.getZkClient();

        List<String> children = zkClient.getChildren(parent);
        if (children.size() != 0) {
            for (String child : children) {
                Stat stat = new Stat();
                String subPath = parent + "/" + child;
                Object object = zkClient.readData(subPath, stat);
                if (null == object) {
                    continue;
                }
                long data = Long.parseLong(object.toString());
                if (data == 0) {
                    continue;
                }
                // 获取当前子节点最近一次修改时间
                long mtime = stat.getMtime();
                log.info("节点[{}]最后一次修改的响应时间为：{}", child, mtime);
                long offset = baseTime - mtime;
                log.info("距离上一次修改相差的毫秒数{}", offset);
                // 判断上次修改时间是否超过5s
                if (offset > 5000) {
                    log.info("{} has no response for more than 5s, will be reset soon...", child);
                    zkClient.writeData(subPath, 0);
                }
            }
        }


    }
}
